﻿using System.Collections.Generic;
using System.Linq;

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using zijian666.Core;
using zijian666.Core.Abstractions;
using zijian666.DI;

namespace UnitTests;

[TestClass]
public class 控制台宿主测试
{
    private IHost _host;

    [TestInitialize]
    public void TestInitialize()
    {
        try
        {
            ErrorReporter.OutChannels = OutChannels.Console;
            _host = Host.CreateDefaultBuilder()
                .AddComponents()
                .AddStartup<Startup>()
                .Build();
            var test = _host.Services.GetService<Startup>();
            Assert.IsTrue(test.IsInit);
            Assert.IsNotNull(test.Builder);
            _host.RunAsync();
            Assert.IsTrue(test.IsStart);
        }
        catch (Exception e)
        {

            throw;
        }
    }

    [TestCleanup]
    public void TestCleanup()
    {
        var test = _host.Services.GetService<Startup>();
        _host.StopAsync().Wait();
        Assert.IsTrue(test.IsStop);
    }

    private class Startup
    {
        public bool IsInit { get; private set; }
        public bool IsStart { get; private set; }
        public bool IsStop { get; private set; }
        public IHostBuilder Builder { get; }

        public Startup(IHostBuilder builder)
        {
            Builder = builder;
        }

        [ConfigureServices]
        public void Init(IServiceCollection services)
        {
            services.AddAutowired();
            IsInit = !IsInit;
        }

        [Configure]
        public void Start() => IsStart = !IsStart;

        [HostStop]
        public void Stop() => IsStop = !IsStop;

    }

    [TestMethod]
    public void 自动注入()
    {
        Assert.IsNotNull(_host.Services.GetService<MyService1>());
        Assert.IsNotNull(_host.Services.GetService<MyService2>());
        Assert.AreEqual(2, _host.Services.GetServices<IFeature>().Count());

        Assert.IsNotNull(_host.Services.GetService<MyService2>().MyService1);
        Assert.IsNotNull(_host.Services.GetService<MyService1>().IFeatures);

        Assert.AreEqual(_host.Services.GetService<MyService2>().MyService1, _host.Services.GetService<MyService1>());
        Assert.AreEqual(2, _host.Services.GetService<MyService1>().IFeatures.Count());

        Assert.IsNotNull(_host.Services.GetService<MyService2>().MyService3);
    }


    [Component, Component(typeof(IFeature))]
    private class MyService1 : IFeature
    {
        public MyService1()
        {
            
        }
        [Autowired]
        public IList<IFeature> IFeatures { get; private set; }
    }

    [Component, Component(typeof(IFeature))]
    private class MyService2 : IFeature
    {
        [Autowired]
        public MyService1 MyService1;
        [Autowired]
        public MyService3 MyService3;
    }

    private interface IMyService3 { }
    [Component(typeof(IMyService3))]
    private class MyService3 : IMyService3
    {

    }
}
